﻿using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
using AForge.Video;
using AForge.Video.DirectShow;
using WindowsFormsGUI.Entidades;

namespace WindowsFormsGUI
{
    public partial class Monedeitor : Form
    {
        #region Atributos

        private bool _existeDispositivo;
        private bool _dispositivoEnEjecucion;

        private FilterInfoCollection _dispositivoDeVideo;
        private VideoCaptureDevice _fuenteDeVideo;

        #endregion

        #region Constructor

        public Monedeitor()
        {
            InitializeComponent();
            BuscarDispositivos();
            HabilitarControles();
        }

        #endregion

        #region Eventos de usuario

        private void BtnIniciarClick(object sender, EventArgs e)
        {
            try
            {
                if (_dispositivoEnEjecucion)
                {
                    DetenerDispositivo();
                }
                else
                {
                    IniciarDispositivo();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
            }
        }

        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            try
            {
                CerrarFormulario(e);
            }
            catch (Exception ex)
            {
                TerminarFuenteDeVideo();
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
            }
        }

        private void BtnCapturarImagenClick(object sender, EventArgs e)
        {
            try
            {
                if (EspacioCamara.Image != null)
                {
                    EspacioImagen.Image = EspacioCamara.Image;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
            }
        }

        private void BtnProcesarImagenClick(object sender, EventArgs e)
        {
            try
            {
                if (EspacioImagen.Image != null)
                {
                    ProcesarImagen();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
            }
        }

        private void BtnGuardarImagenClick(object sender, EventArgs e)
        {
            try
            {
                if (EspacioImagen.Image != null)
                {
                    GuardarImagenEnDisco();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
            }
        }

        #endregion

        #region Metodos de soporte

        private void CerrarFormulario(FormClosingEventArgs e)
        {
            base.OnFormClosing(e);

            if (e.CloseReason == CloseReason.WindowsShutDown) return;

            switch (MessageBox.Show(this, "Esta seguro que desea salir?", "Salir", MessageBoxButtons.YesNo, MessageBoxIcon.Question))
            {
                case DialogResult.No:
                    e.Cancel = true;
                    break;
                case DialogResult.Yes:
                    TerminarFuenteDeVideo();
                    break;
            }
        }

        private void BuscarDispositivos()
        {
            _dispositivoDeVideo = new FilterInfoCollection(FilterCategory.VideoInputDevice);

            if (_dispositivoDeVideo.Count > 0)
            {
                _existeDispositivo = true;
                CargarDispositivos(_dispositivoDeVideo);
            }
            else
            {
                _existeDispositivo = false;
            }
        }

        private void CargarDispositivos(FilterInfoCollection dispositivos)
        {
            foreach (FilterInfo dispositivo in dispositivos)
            {
                cmbDispositivos.Items.Add(dispositivo.Name);
                cmbDispositivos.Text = dispositivo.Name;
            }
        }

        private void IniciarDispositivo()
        {
            if (_existeDispositivo)
            {
                var idDispositivo = cmbDispositivos.SelectedIndex;

                _fuenteDeVideo = new VideoCaptureDevice(_dispositivoDeVideo[idDispositivo].MonikerString);
                _fuenteDeVideo.NewFrame += new NewFrameEventHandler(VideoNuevoFrame);
                _fuenteDeVideo.Start();

                Estado.Text = "Ejecutando dispositivo…";
                btnIniciar.Text = "Detener";

                _dispositivoEnEjecucion = true;

                HabilitarControles();
            }
            else
            {
                Estado.Text = "Error: No se encuenta el dispositivo";
            }
        }

        private void DetenerDispositivo()
        {
            if (_fuenteDeVideo.IsRunning)
            {
                TerminarFuenteDeVideo();

                Estado.Text = "Dispositivo detenido…";
                btnIniciar.Text = "Iniciar";

                _dispositivoEnEjecucion = false;

                HabilitarControles();
            }
        }

        private void TerminarFuenteDeVideo()
        {
            if (_fuenteDeVideo != null && _fuenteDeVideo.IsRunning)
            {
                _fuenteDeVideo.SignalToStop();
                _fuenteDeVideo = null;

                EspacioCamara.Image = null;
            }
        }

        private void VideoNuevoFrame(object sender, NewFrameEventArgs eventArgs)
        {
            var imagen = (Bitmap)eventArgs.Frame.Clone();
            EspacioCamara.Image = imagen;
        }

        private void HabilitarControles()
        {
            cmbDispositivos.Enabled = !_dispositivoEnEjecucion;
        }

        private void ProcesarImagen()
        {
            var moneda = ProcesadorDeImagen.Clasificar(EspacioImagen.Image);

            if (moneda == null)
            {
                Contador.MonedasFalsas++;
            }
            else
            {
                Contador.Agregar(moneda);
            }

            EspacioImagen.Image = null;
        }

        private void GuardarImagenEnDisco()
        {
            saveFileDialog.InitialDirectory = @"D:\img";
            saveFileDialog.ShowDialog();

            if (!string.IsNullOrEmpty(saveFileDialog.FileName))
            {
                switch (saveFileDialog.FilterIndex)
                {
                    case 1:
                        EspacioImagen.Image.Save(saveFileDialog.FileName, ImageFormat.Jpeg);
                        break;
                    case 2:
                        EspacioImagen.Image.Save(saveFileDialog.FileName, ImageFormat.Bmp);
                        break;
                }

                MessageBox.Show("La imágen se guardo correctamente.", "Información", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }

            saveFileDialog.FileName = string.Empty;
        }

        #endregion
    }
}
